import { CommonModule } from '@angular/common';
import {
  Component,
  ElementRef,
  EventEmitter,
  HostListener,
  Input,
  Output,
  ViewChild,
  signal,
  input,
  output,
  effect,
} from '@angular/core';
import {
  CloseIconComponent,
  ResetIconComponent,
  ZoomInIconComponent,
  ZoomOutIconComponent,
} from '../../icons';

@Component({
  selector: 'app-image-preview',
  standalone: true,
  imports: [
    CommonModule,
    CloseIconComponent,
    ZoomInIconComponent,
    ZoomOutIconComponent,
    ResetIconComponent,
  ],
  template: `
    <div class="fullscreen-preview" *ngIf="visible" (click)="close()">
      <!-- 顶部工具栏 -->
      <div class="preview-toolbar" (click)="stopPropagation($event)">
        <button class="toolbar-button" (click)="close()">
          <app-close-icon width="24" height="24"></app-close-icon>
        </button>
        <div class="toolbar-zoom">
          <button class="toolbar-button" (click)="zoomOut()">
            <app-zoom-out-icon width="24" height="24"></app-zoom-out-icon>
          </button>
          <span class="zoom-level">{{ scale() * 100 }}%</span>
          <button class="toolbar-button" (click)="zoomIn()">
            <app-zoom-in-icon width="24" height="24"></app-zoom-in-icon>
          </button>
          <button class="toolbar-button" (click)="resetPosition()">
            <app-reset-icon width="24" height="24"></app-reset-icon>
          </button>
        </div>
      </div>

      <!-- 图片容器 -->
      <div
        class="preview-image-container"
        (mousedown)="startDrag($event)"
        (mousemove)="onDrag($event)"
        (mouseup)="endDrag()"
        (mouseleave)="endDrag()"
        (touchstart)="startDrag($event)"
        (touchmove)="onDrag($event)"
        (touchend)="endDrag()"
        (dblclick)="onDoubleTap()"
        (click)="stopPropagation($event)"
      >
        <img
          [src]="imageUrlValue()"
          alt="预览大图"
          class="preview-image"
          [style.transform]="
            'translate(' + x() + 'px, ' + y() + 'px) scale(' + scale() + ')'
          "
          draggable="false"
        />
      </div>
    </div>
  `,
  styles: `
    .fullscreen-preview {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      background-color: rgba(0, 0, 0, 0.9);
      z-index: 1000;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
    }

    .preview-toolbar {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      padding: 16px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      z-index: 1001;
    }

    .toolbar-button {
      background: rgba(0, 0, 0, 0.5);
      border: none;
      border-radius: 50%;
      width: 40px;
      height: 40px;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      margin: 0 4px;
      color: white;
      transition: background-color 0.2s;
    }

    .toolbar-button:hover {
      background: rgba(0, 0, 0, 0.7);
    }

    .toolbar-zoom {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .zoom-level {
      color: white;
      font-size: 14px;
      min-width: 60px;
      text-align: center;
    }

    .preview-image-container {
      position: relative;
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
    }

    .preview-image {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
      transform-origin: center;
      transition: transform 0.1s ease;
      cursor: grab;
    }

    .preview-image:active {
      cursor: grabbing;
    }
  `,
})
export class ImagePreviewComponent {
  imageUrl = input<string | null>('');
  show = input<boolean>(false);

  closed = output<void>();

  visible = false;
  scale = signal<number>(1);
  x = signal<number>(0);
  y = signal<number>(0);
  imageUrlValue = signal<string>('');

  private startX = 0;
  private startY = 0;
  private isDragging = false;

  constructor() {
    effect(() => {
      this.imageUrlValue.set(this.imageUrl() || '');
    });

    effect(() => {
      this.visible = this.show();
      if (this.show()) {
        this.resetPosition();
      }
    });
  }

  open(imageUrl?: string): void {
    if (imageUrl) {
      this.imageUrlValue.set(imageUrl);
    }
    this.resetPosition();
    this.visible = true;
  }

  close(): void {
    this.visible = false;
    this.closed.emit();
  }

  resetPosition(): void {
    this.scale.set(1);
    this.x.set(0);
    this.y.set(0);
  }

  // 放大
  zoomIn(): void {
    if (this.scale() < 3) {
      this.scale.update((scale) => scale + 0.5);
    }
  }

  // 缩小
  zoomOut(): void {
    if (this.scale() > 0.5) {
      this.scale.update((scale) => scale - 0.5);
    }
  }

  // 开始拖动
  startDrag(event: MouseEvent | TouchEvent): void {
    this.isDragging = true;

    if (event instanceof MouseEvent) {
      this.startX = event.clientX - this.x();
      this.startY = event.clientY - this.y();
    } else {
      // TouchEvent
      this.startX = event.touches[0].clientX - this.x();
      this.startY = event.touches[0].clientY - this.y();
    }
  }

  // 拖动中
  onDrag(event: MouseEvent | TouchEvent): void {
    if (!this.isDragging) return;

    event.preventDefault();

    if (event instanceof MouseEvent) {
      this.x.set(event.clientX - this.startX);
      this.y.set(event.clientY - this.startY);
    } else {
      // TouchEvent
      this.x.set(event.touches[0].clientX - this.startX);
      this.y.set(event.touches[0].clientY - this.startY);
    }
  }

  // 结束拖动
  endDrag(): void {
    this.isDragging = false;
  }

  // 处理双击放大/还原
  onDoubleTap(): void {
    if (this.scale() !== 1) {
      this.resetPosition();
    } else {
      this.scale.set(2);
    }
  }

  // 阻止事件冒泡
  stopPropagation(event: Event): void {
    event.stopPropagation();
  }
}
